'use strict'

const wkthread = require('node:worker_threads')

let allowEvents = [
  'error', 'exit', 'message', 'messageerror', 'online'
]

let win_path_preg = /^[c-z]\:.*/ig;

function abs_path (path) {
  if (process.platform === 'win32') {
    return win_path_preg.test(path)
  }

  return path[0] === '/'
}

function fmt_path (path) {
  if (abs_path(path) || path[0] === '.') return path

  let ds =  process.platform === 'win32' ? '\\' : '/'

  return ('.' + ds + path)
}

/**
 * 
 * @param {string} pathfile 
 * @param {object} options 
 * @returns {worker}
 */
function runWorkerThread (pathfile, options = {}) {

  if (!options.eval) {
    pathfile = fmt_path(pathfile)
  }

  if (options.__fail_count__ === undefined) {
    Object.defineProperty(options, '__fail_count__', {
      configurable: false,
      writable: true,
      enumerable: false,
      value: 0
    })
  }

  let events = options.events || {}

  let subserv = new wkthread.Worker(pathfile, options)

  for (let k in events) {
    if (typeof events[k] !== 'function' || allowEvents.indexOf(k) < 0) continue
    if (k === 'online') {
      subserv.on(k, () => {
        events[k](subserv)
      })

      continue
    }

    subserv.on(k, (val) => {
      events[k](subserv, val)
    })
  }

  if (!events.error || typeof events.error !== 'function') {
    subserv.on('error', err => {
      console.error(err)
    })
  }

  subserv.on('exit', (code) => {
    if (options.restart) {
      switch (options.restart) {
        case 'none':
          break

        case 'fail':
          if (code === 0) break

        case 'fail-count':
          if (code) options.__fail_count__ += 1
          if (options.restartLimit 
            && typeof options.restartLimit === 'number' 
            && options.__fail_count__ > options.restartLimit)
          {
            break
          }
        case 'always':
        default:
          if (options.restartDelay && typeof options.restartDelay === 'number') {
            setTimeout(() => {
              runWorkerThread(pathfile, options)
            }, options.restartDelay)
          } else {
            runWorkerThread(pathfile, options)
          }

      }

    }

  })
  
  return subserv
}

module.exports = runWorkerThread
